package com.pengju.eshop.utils

import android.content.ComponentName
import android.content.Context
import android.util.Log
import androidx.fragment.app.FragmentActivity
import androidx.navigation.ActivityNavigator
import androidx.navigation.NavController
import androidx.navigation.NavGraph
import androidx.navigation.NavGraphNavigator
import androidx.navigation.fragment.DialogFragmentNavigator
import androidx.navigation.fragment.FragmentNavigator
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.pengju.eshop.R
import com.pengju.eshop.model.BottomBar
import com.pengju.eshop.model.Destination
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.lang.reflect.Type

object NavUtil {
    private const val TAG = "NavUtil"
    private var destinationMap: Map<String, Destination>? = null
    private val gson by lazy { Gson() }

    /**
     * 解析json文件为 Destination的hashMap
     */
    fun getDestinations(context: Context): HashMap<String, Destination>? {
        val assetsManager = context.assets
        val inputStream = assetsManager.open("destination.json")
        val bufferReader = BufferedReader(InputStreamReader(inputStream))
        try {
            var line = ""
            val stringBuilder = StringBuilder()
            while (bufferReader.readLine().also { line = it } != null) {
                stringBuilder.append(line)
            }
            val type = object : TypeToken<Map<String, Destination>>() {}.type
            return gson.fromJson(stringBuilder.toString(), type)
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            inputStream.close()
            bufferReader.close()
        }
        return null
    }

    fun buildNavGraph(activity: FragmentActivity, navController: NavController, containerID: Int) {
        val content = parseFile(activity.baseContext, "destination.json")
        Log.d("NavUtil", "content = $content")
        val type: Type = object : TypeToken<Map<String, Destination>>() {}.type
        destinationMap = gson.fromJson(content, type)
        val provider = navController.navigatorProvider
        val navGraphNavigator = provider.getNavigator(NavGraphNavigator::class.java)
        val navGraph = NavGraph(navGraphNavigator)
        provider.addNavigator(navGraphNavigator)
        destinationMap?.entries?.forEach {
            val destination = it.value
            Log.d("NavUtil", "key: ${it.key}  value: ${it.value}")
            when(destination.destType.lowercase()){
                "activity" -> {
                    val navigator = provider.getNavigator(ActivityNavigator::class.java)
                    val node = navigator.createDestination()
                    node.id = destination.pageID
                    node.setComponentName(ComponentName(activity.packageName, destination.clazzName))
                    navGraph.addDestination(node)
                }
                "fragment" -> {
                    val navigator = provider.getNavigator(FragmentNavigator::class.java)
                    val node = navigator.createDestination()
                    node.id = destination.pageID
                    node.setClassName(destination.clazzName)
                    navGraph.addDestination(node)
                }
                "dialog" -> {
                    val navigator = provider.getNavigator(DialogFragmentNavigator::class.java)
                    val node = navigator.createDestination()
                    node.id = destination.pageID
                    node.setClassName(destination.clazzName)
                    navGraph.addDestination(node)
                }
            }
            if (destination.asStarter) {
                Log.d("NavUtil", "starter is ${destination.tag}")
                navGraph.setStartDestination(destination.pageID)
            }
        }
        navController.graph = navGraph
    }
    private fun parseFile(context: Context, fileName: String): String? {
        val assetsManager = context.assets
        val inputStream = assetsManager.open(fileName)
        val bufferReader = BufferedReader(InputStreamReader(inputStream))
        try {
            var line: String
            val stringBuilder = StringBuilder()
            while (bufferReader.readLine().also { line = it } != null) {
                stringBuilder.append(line)
            }
            Log.d(TAG, "parseFile: result = $stringBuilder")
            return stringBuilder.toString()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            inputStream.close()
            bufferReader.close()
        }
        return null
    }

    fun buildBottomBar(bottomNavigationView: BottomNavigationView) {
        val config = parseFile(bottomNavigationView.context, "main_tabs_config.json")
        val bottomBar = gson.fromJson(config, BottomBar::class.java)
        val menu = bottomNavigationView.menu
        destinationMap?.forEach{
            Log.d(TAG, "buildBottomBar: key: ${it.key}  value: ${it.value}")
        }
        bottomBar.tabs.forEach { tab ->
//            Log.d(TAG, "buildBottomBar: tab = $tab  map: $destinationMap")
            if (tab.enable) {
                destinationMap?.get(tab.tag)?.let { destination ->
                    Log.d(TAG, "buildBottomBar: destination = $destination")
                    val menuItem = menu.add(0, destination.pageID, tab.index, tab.title)
                    menuItem.setIcon(R.drawable.ic_dashboard_black_24dp)

                }
            }
        }
    }
}